//
// 208prop.cpp for 208prop in /home/reboul_a//work/tek2/svn-projet-pitek/Math/208
//
// Made by anthony reboul
// Login   <reboul_a@epitech.net>
//
// Started on  Mon Jun  6 13:39:57 2011 anthony reboul
// Last update Fri May 25 10:34:07 2012 pierrick druart
//

#include <math.h>
#include <string.h>
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <fcntl.h>
#include <string>
#include <iostream>
#include <fstream>
#include <sstream>
#include "209.hpp"

Math::Math()
{
  this->_n = 0;
  this->_res9 = 0;
  this->_k = 0;
}

Math::~Math()
{
}

double		Math::Ckn(int n, int k)
{
  double		res = 0;

  res = facto(n) / (facto(k) * (facto(n - k)));
  return (res);
}

double		Math::Tx(double Ckn, double p, int n, int x)
{
  double	res = 0;

  res = n * Ckn * pow(p, x) * pow((1 - p), n - x);
  return (res);
}

double		Math::Moy()
{
  std::list<std::string>::iterator      it;
  double	       			res = 0, tmp = 0;
  std::string				stmp;

  it = this->obs.begin();
  while (it != this->obs.end())
    {
      stmp = *it;
      tmp = atof(stmp.c_str());
      it++;
      stmp = *it;
      tmp = tmp * atof(stmp.c_str());
      it++;
      res = res + tmp;
    }
  return (res / this->_n);
}

double		Math::proba(double Moy, int n)
{
  double	res = 0;

  res = Moy / n;
  return (res);
}

void		Math::afftab(void)
{
  std::list<std::string>::iterator	it;
  std::string				nb, obs;
  int					k = 0;

  it = this->obs.begin();
  std::cout << "|" << std::flush;
  while (it != this->obs.end() && it != this->nb.end())
    {
      if (k == 0)
	{
	  obs = *it;
	  std::cout << " " << obs << "    | ";
	  k = 1;
	}
      else
	k = k - k;
      ++it;
    }
  std::cout << std::endl;
  it = this->obs.begin();
  std::cout << "|" << std::flush;
  k = 0;
  while (it != this->obs.end() && it != this->nb.end())
    {
      if (k == 0)
	k = 1;
      else
	{
	  obs = *it;
	  this->_n = atof(obs.c_str()) + this->_n;
	  std::cout << " " << obs << "    | ";
	  k = k - k;
	}
      ++it;
    }
  std::cout << std::endl;
  std::cout << "Moyenne : " << Moy() << std::endl;
  std::cout << "Proba : " << proba(Moy() , this->_n) << std::endl;
  for (k = 0; k != 9; k++)
    {
      this->_res9 += Tx(Ckn(this->_n , k), proba(Moy(), this->_n), this->_n, k);
      std::cout << "x = " << k <<
	" Tx = " << Tx(Ckn(this->_n , k), proba(Moy(), this->_n), this->_n, k) << std::endl;
		       }
	std::cout << "x = 9 Tx = " << 100 - this->_res9 << std::endl;
    }

  double          Math::facto(int number)
  {
    double temp;

    if (number <= 1)
      return (1);
    temp = number * facto(number - 1);
    return (temp);
  }

  double			Math::proportion()
  {
    double		res2 = 0;
    double		res = 0;
    std::string		nbr;
    char			*nb;
    std::list<std::string>::iterator	it;

    it = this->obs.begin();
    while (it != this->obs.end())
      {
	nbr = *it;
	nb = const_cast<char *>(nbr.c_str());
	if (atof(nb) >= 960)
	  res++;
	++it;
      }
    res2 = atof(const_cast<char *>(this->howmany.c_str()));
    res = res / res2;
    return (res);
  }

  void			Math::parseAll()
  {
    std::list<std::string>::iterator      it;
    std::string			elem;

    it = this->nb.begin();
    while (it != this->nb.end())
      {
	std::istringstream	iss(*it);
	while (std::getline(iss, elem, ' '))
	  {
	    if (elem != "")
	      this->obs.push_back(elem);
	  }
	++it;
      }
  }

  void			Math::parseCmd(char **av)
  {
    std::ifstream file(av[1]);

    if (file)
      {
	std::string line;
	while (std::getline(file, line))
	  {
	    this->nb.push_back(line);
	  }
      }
    else
      {
	std::cout << "File doesn't exist !" << std::endl;
	exit(1);
      }
  }

  std::string		Math::getHowmany()
  {
    return (this->howmany);
  }

  int			main(int ac, char **av)
  {
    Math			m;

    if (ac > 1)
      {
	m.parseCmd(av);
	m.parseAll();
	m.afftab();
      }
    else
      std::cout << "Usage: ./209 file.txt" << std::endl;
    return (0);
  }
